﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SetFileToOpen
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;//这一行是关键      

        }

        bool flag = true;

        private void button1_Click(object sender, EventArgs e)
        {
            if (flag==false)
            {
                MessageBox.Show("执行中请勿重复点击");
                return;
            }
            
            try
            {
                flag = false;
                IIdentity ii = WindowsIdentity.GetCurrent();
                NTAccount newUser = new NTAccount(ii.Name);
                this.txtExMsg.Text += newUser.Value + "\r\n";

                this.txtTrueMsg.Text = "";
                this.txtFalseMsg.Text = "";
                string path = this.textBox1.Text;


                if (string.IsNullOrEmpty(path))
                {
                    MessageBox.Show("请填写路径");
                    return;
                }
                Thread t = new Thread(new ParameterizedThreadStart(SetFolder));
                t.Priority = ThreadPriority.Highest;
                t.Start();


            }
            catch (Exception ex)
            {
                this.txtExMsg.Text += ex.Message + "\r\n";
            }
        }

        public  void SetFolder(object o)
        {
            string path = this.textBox1.Text;
            IIdentity ii = WindowsIdentity.GetCurrent();
            NTAccount newUser = new NTAccount(ii.Name);
            string user = newUser.Value;

            #region 设置文件夹
            //设置该文件夹访问权限
            if (!SetFolderACL(path, user, FileSystemRights.FullControl, AccessControlType.Allow))
            {
                SetFolderACL(path, "EVERYONE", FileSystemRights.FullControl, AccessControlType.Allow);
                this.txtExMsg.Text += "False开启文件夹失败\r\n";
            }

            this.txtTrueMsg.Text = "正在获取文件列表请稍等..." + this.txtTrueMsg.Text;
            string[] folders = Directory.GetDirectories(path);
            this.txtTrueMsg.Text += path + "开启成功\r\n";
            this.lblFNum.Text += folders.Length.ToString();
            var count = 0;
            foreach (var item in folders)
            {
                count++;
                SetFolderACL(item, user, FileSystemRights.FullControl, AccessControlType.Allow);
                SetFolderACL(item,"EVERYONE", FileSystemRights.FullControl, AccessControlType.Allow);

                this.txtTrueMsg.Text = item + "开启成功\r\n" + this.txtTrueMsg.Text;
                this.lblFTNum.Text = "已完成文件夹数量："+count;
                this.lblState.Text = "当前状态："+Thread.CurrentThread.ThreadState;
            } 
            #endregion
            #region 设置文件

            if (!this.checkBox2.Checked)
            {
                this.txtTrueMsg.Text = "正在获取所有文件列表...\r\n" + this.txtTrueMsg.Text;
                List<FileInformation> list = DirectoryAllFiles.GetAllFiles(new System.IO.DirectoryInfo(@path));
                //if (list.Where(t => t.FileName.ToLower().Contains("android")).Any()) Console.WriteLine("true");
                this.lblFileNum.Text = "文件数量：" + list.Count;
                count = 0;
                foreach (var item in list)
                {
                    count++;
                    try
                    {
                        //获取文件信息
                        FileInfo fileInfo = new FileInfo(item.FilePath);
                        //获得该文件的访问权限
                        FileSecurity fileSecurity = fileInfo.GetAccessControl();


                        fileSecurity.SetOwner(newUser);
                        //fileSecurity.SetOwner()
                        //添加ereryone用户组的访问权限规则 完全控制权限
                        fileSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));
                        //添加Users用户组的访问权限规则 完全控制权限
                        fileSecurity.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.FullControl, AccessControlType.Allow));
                        //设置访问权限
                        fileInfo.SetAccessControl(fileSecurity);

                        this.txtTrueMsg.Text = "成功：" + item.FilePath + "\n" + this.txtTrueMsg.Text;
                        this.txtTrueMsg.Text = "-------------------------------------------------------------------------------" + this.txtTrueMsg.Text;

                    }
                    catch (Exception ex)
                    {
                        this.txtFalseMsg.Text += "\n-------------------------------------------------------------------------------";
                        this.txtFalseMsg.Text += "\n" + ex.Message;
                        this.txtFalseMsg.Text += "\n文件名：" + item.FilePath;
                        this.txtFalseMsg.Text += "\n-------------------------------------------------------------------------------";
                    }
                    finally
                    {
                        this.lblState.Text = "当前状态：" + Thread.CurrentThread.ThreadState;
                        this.lblFileTrueNum.Text= "已完成文件量："+count;
                    }

                }


                this.txtTrueMsg.Text += "\r\n\r\n";
                this.txtTrueMsg.Text += "本次共为" + list.Count + "个文件开启了权限！";
            }
            #endregion
            flag = true;
            MessageBox.Show("执行完成");
        }

        public static bool SetFolderACL(String FolderPath, String UserName, FileSystemRights Rights, AccessControlType AllowOrDeny)

        {

            InheritanceFlags inherits = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;

            return SetFolderACL(FolderPath, UserName, Rights, AllowOrDeny, inherits, PropagationFlags.None, AccessControlModification.Add);

        }

        public static bool SetFolderACL(String FolderPath, String UserName, FileSystemRights Rights, AccessControlType AllowOrDeny, InheritanceFlags Inherits, PropagationFlags PropagateToChildren, AccessControlModification AddResetOrRemove)

        {

            bool ret;

            DirectoryInfo folder = new DirectoryInfo(FolderPath);

            DirectorySecurity dSecurity = folder.GetAccessControl(AccessControlSections.All);

            FileSystemAccessRule accRule = new FileSystemAccessRule(UserName, Rights, Inherits, PropagateToChildren, AllowOrDeny); dSecurity.ModifyAccessRule(AddResetOrRemove, accRule, out ret);

            folder.SetAccessControl(dSecurity);

            return ret;

        }
    }

    public class DirectoryAllFiles
    {
        static List<FileInformation> FileList = new List<FileInformation>();
        public static List<FileInformation> GetAllFiles(DirectoryInfo dir)
        {
            FileInfo[] allFile = dir.GetFiles();
            foreach (FileInfo fi in allFile)
            {
                FileList.Add(new FileInformation { FileName = fi.Name, FilePath = fi.FullName });
            }
            DirectoryInfo[] allDir = dir.GetDirectories();
            foreach (DirectoryInfo d in allDir)
            {
                GetAllFiles(d);
            }
            return FileList;
        }
    }



    public class FileInformation
    {
        public string FileName { get; set; }
        public string FilePath { get; set; }
    }
}
